import {Graph, Path, Shape} from '@antv/x6'
import Input from '../components/NodeTheme/Input.vue'
import Output from '../components/NodeTheme/Output.vue'
import Attrs from '../components/NodeTheme/Attrs.vue'
import Deduplication from '../components/NodeTheme/Deduplication.vue'
import Default from '../components/NodeTheme/Default.vue'
import FilterOpera from '../components/NodeTheme/Filter.vue'
import Pca from '../components/NodeTheme/Pca.vue'
import Standard from '../components/NodeTheme/Standard.vue'
import VueShapeText from '../components/NodeTheme/VueShapeText/index'
import '@antv/x6-vue-shape'

const insertCss = require('insert-css')

insertCss(`
  @keyframes ant-line {
    to {
        stroke-dashoffset: -1000
    }
  }
`)

/**
 * @desc 初始化面板配置
 * @param check 查看模式
 */
const graphOptions = (check = false, width = 800, height = 600) => {
    Graph.registerVueComponent(
        "vue-shape-text",
        {
            template: `
                <VueShapeText/>`,
            components: {
                VueShapeText,
            },
        },
        true
    );
    Graph.registerEdge(
        'dag-edge',
        {
            inherit: 'edge',
            attrs: {
                line: {
                    stroke: '#C2C8D5',
                    strokeWidth: 2,
                    targetMarker: {
                        name: 'block',
                        width: 12,
                        height: 8
                    }
                }
            }
        },
        true
    )
    Graph.registerConnector(
        'algo-connector',
        (s, e) => {
            const offset = 4
            const deltaY = Math.abs(e.y - s.y)
            const control = Math.floor((deltaY / 3) * 2)

            const v1 = {x: s.x, y: s.y + offset + control}
            const v2 = {x: e.x, y: e.y - offset - control}

            return Path.normalize(
                `M ${s.x} ${s.y}
           L ${s.x} ${s.y + offset}
           C ${v1.x} ${v1.y} ${v2.x} ${v2.y} ${e.x} ${e.y - offset}
           L ${e.x} ${e.y}
          `
            )
        },
        true
    )
    return {
        container: document.getElementById('container'),
        width: width,
        height: height,
        // 定制节点和边的交互行为 ==> boolean 节点或边是否可交互
        interacting: check
            ? {
                nodeMovable: false,
                edgeMovable: false,
                magnetConnectable: false,
                vertexDeletable: false
            }
            : true,
        // 对齐线
        snapline: true,
        panning: {
            enabled: true,
            modifiers: 'shift',
        },
        // 撤销/重做
        history: !check,
        // 点选/框选
        selecting: {
            enabled: true,
            multiple: !check, // 多选【开启】
            rubberband: !check, // 启用框选【关闭】
            movable: !check,
            rubberEdge: !check,
            rubberNode: !check,
        },
        background: {
          color: '#ffffff'
        },
        // 显示网格 // 'dot' | 'fixedDot' | 'mesh'
        grid: {
            visible: true,
            size: 20, // 网格大小
            type: 'mesh',
            args: {
                color: '#e9e9e9',
                // color: '#ffffff',
                thickness: 2 // 网格线宽度/网格点大小
            }
        },
        // 滚动
        scroller: {
            enabled: false,
            pageVisible: false, // 是否分页
            pageBreak: false,
            pannable: true // 是否平移
        },
        // 滚轮缩放 MouseWheel
        mousewheel: {
            enabled: true,
            zoomAtMousePosition: true,
            modifiers: ['ctrl', 'meta'],
            maxScale: 3,
            minScale: 0.3
        },
        // 连线规则
        connecting: {
            connector: 'algo-connector',
            anchor: 'center',
            connectionPoint: 'anchor',
            // 是否允许连接到画布空白位置的点，默认为 true。
            allowBlank: false,
            // 距离节点或者连接桩 20px 时会触发自动吸附
            snap: {
                radius: 20
            },
            highlight: true,
            allowMulti: false, // 是否允许在相同的起始节点和终止之间创建多条边
            allowNode: false, // 是否允许边链接到节点（非节点上的链接桩）
            allowLoop: false, // 是否允许创建循环连线，即边的起始节点和终止节点为同一节点，
            allowEdge: false, // 是否允许边链接到另一个边
            // 拽出新的边
            createEdge() {
                return new Shape.Edge({
                    shape: 'dag-edge',
                    attrs: {
                        line: {
                            strokeDasharray: '5 5',
                            stroke: '#456d89',
                            targetMarker: {
                                name: 'block',
                                width: 12,
                                height: 8
                            }
                        }
                    },
                    zIndex: -1
                })
            },
            validateMagnet({magnet}) {
                // return magnet.getAttribute('port-group') !== 'top'
                // 限制连线配置
                return true
            },
            validateConnection({
                                   sourceView,
                                   targetView,
                                   sourceMagnet,
                                   targetMagnet,
                               }) {
                if (sourceView === targetView) {
                    return false
                }
                if (!sourceMagnet) {
                    return false
                }
                if (!targetMagnet) {
                    return false
                }
                return true
            },
        },
        // 连线高亮
        highlighting: {
            // 连线过程中，自动吸附到链接桩时被使用。
            magnetAdsorbed: {
                name: 'stroke',
                args: {
                    attrs: {
                        fill: '#fff',
                        stroke: '#31d0c6',
                        strokeWidth: 4
                    }
                }
            }
        },
        // 修改大小
        resizing: check
            ? false
            : {
                enabled: false,
                minWidth: 64, // 最小宽
                maxWidth: 64 * 2, // 最大宽
                minHeight: 105 / 2, // 最小高
                maxHeight: 105 * 2, // 最大高
                orthogonal: true, // 是否显示中间调整点，默认为 true
                restricted: false, // 调整大小边界是否可以超出画布边缘
                preserveAspectRatio: true // 调整大小过程中是否保持节点的宽高比例
            },
        rotating: false, // 不能旋转
        keyboard: !check, // 按键操作
        clipboard: !check, // 剪切板
        autoResize: true,
        onToolItemCreated({tool}) {
            const options = tool.options
            if (options && options.index % 2 === 1) {
                tool.setAttrs({fill: 'red'})
            }
        }
    }
}

// 链接桩样式
const portStyle = {
    width: 12,
    r: 4, // 半径
    // 当 magnet 属性为 true 时，表示该元素可以被链接，即在连线过程中可以被当做连线的起点或终点，与链接桩类似。
    magnet: true,
    // stroke: '#5F95FF',
    stroke: '#C2C8D5',
    strokeWidth: 1,
    fill: '#fff',
    zIndex: 1,
    style: {
        visibility: 'hidden'
    }
}

// 链接桩配置
const ports = {
    // 设置链接桩分组
    groups: {
        top: {
            // 定义连接柱的位置，如果不配置，将显示为默认样式
            position: 'top',
            // 定义连接柱的样式
            attrs: {
                circle: {
                    ...portStyle
                }
            }
        },
        right: {
            position: 'right',
            attrs: {
                circle: {
                    ...portStyle
                }
            }
        },
        bottom: {
            position: 'bottom',
            attrs: {
                circle: {
                    ...portStyle
                }
            }
        },
        left: {
            position: 'left',
            attrs: {
                circle: {
                    ...portStyle
                }
            }
        },
        absolute: {
            position: 'absolute',
            attrs: {
                circle: {
                    r: 6,
                    magnet: true,
                    stroke: '#008CFF',
                    strokeWidth: 2,
                    fill: '#fff'
                }
            }
        }
    },
    // 链接桩
    items: [
        {
            group: 'top'
        },
        // {
        //     group: 'right'
        // },
        {
            group: 'bottom'
        },
        // {
        //     group: 'left'
        // }
    ]
}

// 自定义节点的名称
const SETTING_SHAPE_NAME = 'setting-shape'

const DAG_NAME_GROUP = {
    input: 'input',
    output: 'output',
    filterOpera: 'filterOpera',
    default: 'default',
    attrs: 'attrs',
    standard: 'standard',
    deduplication: 'deduplication',
    pca: 'pca'
}
// 动态计算宽高比
const transformToPercent = (target, sum, font) => {
    // 相对节点的大小
    const percent = (target / sum).toFixed(2) * 100
    return `${percent}${font ? 'px' : '%'}`
}

// 自定义对象节点的配置，需要展示更多的节点内容在这里去添加，并更新数据
const SettingNodeOptions = {
    inherit: 'rect',
    width: 180,
    height: 36,
    markup: [
        {
            tagName: 'rect',
            selector: 'body'
        },
        {
            tagName: 'image',
            selector: 'settingImage'
        },
        {
            tagName: 'text',
            selector: 'settingName'
        }
    ],
    attrs: {
        body: {
            class: SETTING_SHAPE_NAME,
            stroke: '#5F95FF',
            strokeWidth: 1,
            fill: 'rgba(95,149,255,0.05)',
            fillOpacity: 0.75
        },
        settingImage: {
            refWidth: transformToPercent(32, 64),
            refHeight: transformToPercent(32, 64),
            refX: transformToPercent(16, 64),
            refY: transformToPercent(8, 64),
            textAnchor: 'middle',
            textVerticalAnchor: 'bottom',
            anchor: 'middle',
            verticalAnchor: 'bottom'
        },
        settingName: {
            refWidth: '100%',
            refX: transformToPercent(32, 64),
            refY: transformToPercent(60, 64),
            textAnchor: 'middle',
            textVerticalAnchor: 'bottom',
            fontSize: 12,
            fill: '#262626'
            // 超出换行
            // textWrap: {
            //     width: 64,
            //     breakWord: false, // 是否截断单词
            // },
        }
    },
    ports: {...ports}
}
const DAG_NODE_Options = {
    input: {
        inherit: 'vue-shape',
        width: 180,
        height: 36,
        component: {
            template: `<Input/>`,
            components: {
                Input
            }
        },
        ports: {
            groups: {
                top: {
                    position: 'top',
                    attrs:
                        {
                            circle: {
                                r: 4,
                                magnet: true,
                                stroke:
                                    '#C2C8D5',
                                strokeWidth: 1,
                                fill: '#fff'
                            }
                        }
                },
                bottom: {
                    position: 'bottom',
                    attrs: {
                        circle: {
                            r: 4,
                            magnet:
                                true,
                            stroke: '#C2C8D5',
                            strokeWidth: 1,
                            fill: '#fff'
                        }
                    }
                }
            }
        }
    },
    output: {
        inherit: 'vue-shape',
        width: 180,
        height: 36,
        component: {
            template: `
                <Output/>`,
            components: {
                Output
            }
        },
        ports: {
            groups: {
                top: {
                    position: 'top',
                    attrs:
                        {
                            circle: {
                                r: 4,
                                magnet: true,
                                stroke:
                                    '#C2C8D5',
                                strokeWidth: 1,
                                fill: '#fff'
                            }
                        }
                },
                bottom: {
                    position: 'bottom',
                    attrs: {
                        circle: {
                            r: 4,
                            magnet:
                                true,
                            stroke: '#C2C8D5',
                            strokeWidth: 1,
                            fill: '#fff'
                        }
                    }
                }
            }
        }
    },
    filterOpera: {
        inherit: 'vue-shape',
        width: 180,
        height: 36,
        component: {
            template: `
                <FilterOpera/>`,
            components: {
                FilterOpera
            }
        },
        ports: {
            groups: {
                top: {
                    position: 'top',
                    attrs:
                        {
                            circle: {
                                r: 4,
                                magnet: true,
                                stroke:
                                    '#C2C8D5',
                                strokeWidth: 1,
                                fill: '#fff'
                            }
                        }
                },
                bottom: {
                    position: 'bottom',
                    attrs: {
                        circle: {
                            r: 4,
                            magnet:
                                true,
                            stroke: '#C2C8D5',
                            strokeWidth: 1,
                            fill: '#fff'
                        }
                    }
                }
            }
        }
    },
    default: {
        inherit: 'vue-shape',
        width: 180,
        height: 36,
        component: {
            template: `
                <Default/>`,
            components: {
                Default
            }
        },
        ports: {
            groups: {
                top: {
                    position: 'top',
                    attrs:
                        {
                            circle: {
                                r: 4,
                                magnet: true,
                                stroke:
                                    '#C2C8D5',
                                strokeWidth: 1,
                                fill: '#fff'
                            }
                        }
                },
                bottom: {
                    position: 'bottom',
                    attrs: {
                        circle: {
                            r: 4,
                            magnet:
                                true,
                            stroke: '#C2C8D5',
                            strokeWidth: 1,
                            fill: '#fff'
                        }
                    }
                }
            }
        }
    },
    attrs: {
        inherit: 'vue-shape',
        width: 180,
        height: 36,
        component: {
            template: `
                <Attrs/>`,
            components: {
                Attrs
            }
        },
        ports: {
            groups: {
                top: {
                    position: 'top',
                    attrs:
                        {
                            circle: {
                                r: 4,
                                magnet: true,
                                stroke:
                                    '#C2C8D5',
                                strokeWidth: 1,
                                fill: '#fff'
                            }
                        }
                },
                bottom: {
                    position: 'bottom',
                    attrs: {
                        circle: {
                            r: 4,
                            magnet:
                                true,
                            stroke: '#C2C8D5',
                            strokeWidth: 1,
                            fill: '#fff'
                        }
                    }
                }
            }
        }
    },
    standard: {
        inherit: 'vue-shape',
        width: 180,
        height: 36,
        component: {
            template: `
                <Standard/>`,
            components: {
                Standard
            }
        },
        ports: {
            groups: {
                top: {
                    position: 'top',
                    attrs:
                        {
                            circle: {
                                r: 4,
                                magnet: true,
                                stroke:
                                    '#C2C8D5',
                                strokeWidth: 1,
                                fill: '#fff'
                            }
                        }
                },
                bottom: {
                    position: 'bottom',
                    attrs: {
                        circle: {
                            r: 4,
                            magnet:
                                true,
                            stroke: '#C2C8D5',
                            strokeWidth: 1,
                            fill: '#fff'
                        }
                    }
                }
            }
        }
    },
    deduplication: {
        inherit: 'vue-shape',
        width: 180,
        height: 36,
        component: {
            template: `
                <Deduplication/>`,
            components: {
                Deduplication
            }
        },
        ports: {
            groups: {
                top: {
                    position: 'top',
                    attrs:
                        {
                            circle: {
                                r: 4,
                                magnet: true,
                                stroke:
                                    '#C2C8D5',
                                strokeWidth: 1,
                                fill: '#fff'
                            }
                        }
                },
                bottom: {
                    position: 'bottom',
                    attrs: {
                        circle: {
                            r: 4,
                            magnet:
                                true,
                            stroke: '#C2C8D5',
                            strokeWidth: 1,
                            fill: '#fff'
                        }
                    }
                }
            }
        }
    },
    pca: {
        inherit: 'vue-shape',
        width: 180,
        height: 36,
        component: {
            template: `
                <Pca/>`,
            components: {
                Pca
            }
        },
        ports: {
            groups: {
                top: {
                    position: 'top',
                    attrs:
                        {
                            circle: {
                                r: 4,
                                magnet: true,
                                stroke:
                                    '#C2C8D5',
                                strokeWidth: 1,
                                fill: '#fff'
                            }
                        }
                },
                bottom: {
                    position: 'bottom',
                    attrs: {
                        circle: {
                            r: 4,
                            magnet:
                                true,
                            stroke: '#C2C8D5',
                            strokeWidth: 1,
                            fill: '#fff'
                        }
                    }
                }
            }
        }
    },
}

const colors = ['#2AC94F', '#0AAEFF', '#DB5A6B', '#057748', '#2E4E7E', '#845A33']

export {
    graphOptions,
    portStyle,
    ports,
    SETTING_SHAPE_NAME,
    DAG_NAME_GROUP,
    transformToPercent,
    SettingNodeOptions,
    DAG_NODE_Options,
    colors
}
